package com.atldy.commerce.service;

import cn.hutool.core.collection.CollUtil;
import com.netflix.hystrix.HystrixCommand;
import com.netflix.hystrix.HystrixCommandGroupKey;
import com.netflix.hystrix.HystrixCommandKey;
import com.netflix.hystrix.HystrixCommandProperties;
import com.netflix.hystrix.HystrixThreadPoolKey;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.client.ServiceInstance;

import java.util.List;

import static com.netflix.hystrix.HystrixCommandProperties.ExecutionIsolationStrategy.THREAD;

/**
 * @version 1.0
 * @Author: li-dong-yang
 * @CreateTime: 2021-09-08 21:45
 * @Description： 编码形式使用 Hystrix  给 HystrixServiceCommand 实现包装
 */
@Slf4j
public class HystrixServiceCommand extends HystrixCommand<List<ServiceInstance>> {

    private final NacosClientService nacosClientService;

    private final String serviceId;

    public HystrixServiceCommand(NacosClientService nacosClientService, String serviceId) {
        //开启线程隔离 舱壁模式
        super(Setter.withGroupKey(
                //分组，便于统计
                HystrixCommandGroupKey.Factory.asKey("nacosClientService"))
                //独一无二的标识
                .andCommandKey(HystrixCommandKey.Factory.asKey("nacosClientHystrixServiceCommand"))
                //线程池标识
                .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("nacosClientHystrixThreadPoolKey"))
                //线程池配置
                .andCommandPropertiesDefaults(
                        HystrixCommandProperties.Setter()
                                // 线程池隔离策率
                                .withExecutionIsolationStrategy(THREAD)
                                // 开启降级
                                .withFallbackEnabled(true)
                                // 开启熔断器
                                .withCircuitBreakerEnabled(true)
                )
        );

        this.nacosClientService = nacosClientService;
        this.serviceId = serviceId;
    }

    /**
     * <h3>要保护的方法卸载run中</h3>
     */
    @Override
    protected List<ServiceInstance> run() throws Exception {
        int i = 10 / 0;
        log.info("use hystrix command annotation to get nacos client info: [{}], [{}]",
                serviceId, Thread.currentThread().getName());
        return nacosClientService.getServiceInstance(serviceId);
    }

    /**
     * <h3>降级兜底方法</h3>
     */
    @Override
    protected List<ServiceInstance> getFallback() {
        log.error("服务名称是：{}", serviceId);
        return CollUtil.newArrayList();
    }
}